package design;

import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;

/**
 * Created with IntelliJ IDEA.
 * Description:
 * User: Li_yizYa
 * Date: 2025/8/29
 * Time: 21:54
 */
// 抽象主题
//interface Movie {
//    void play();
//}
//// 真实主题
//class RealMovie implements Movie {
//    @Override
//    public void play() {
//        System.out.println("正在播放电影《爵迹》");
//    }
//}
//
//class MovieProxy implements Movie { // 代理也实现同样的接口
//    private RealMovie realMovie; // 持有真实对象的引用
//
//    public MovieProxy(RealMovie realMovie) {
//        this.realMovie = realMovie;
//    }
//
//    @Override
//    public void play() {
//        // 前置处理
//        System.out.println("[代理] 播放前先来一段广告~");
//        // 核心处理
//        realMovie.play();
//        // 后置处理
//        System.out.println("[代理] 播放后再来一段广告~");
//    }
//}
//
//public class StaticProxyDemo {
//    public static void main(String[] args) {
//        // 创建真实对象
//        RealMovie realMovie = new RealMovie();
//        // 创建代理对象，并将真实对象注入
//        MovieProxy movieProxy = new MovieProxy(realMovie);
//
//        // 客户端只和代理打交道，不知道真实对象的存在
//        movieProxy.play();
//    }
//}
// 抽象主题
interface Movie {
    void play();
}
// 真实主题
class RealMovie implements Movie {
    @Override
    public void play() {
        System.out.println("正在播放电影《爵迹》");
    }
}

// 调用处理器
class MyInvocationHandler implements InvocationHandler {
    private Object target; // 被代理的真实对象

    public MyInvocationHandler(Object target) {
        this.target = target;
    }

    // 所有对代理对象的方法调用，都会转发到这个方法里来
    @Override
    public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
        // 前置处理
        System.out.println("[代理] 播放前先来一段广告~");
        // 调用真实对象的方法
        Object result = method.invoke(target, args);
        // 后置处理
        System.out.println("[代理] 播放后再来一段广告~");
        return result;
    }
}

public class StaticProxyDemo {
    public static void main(String[] args) {
        // 创建真实对象
        RealMovie realMovie = new RealMovie();
        // 创建InvocationHandler，并传入真实对象
        InvocationHandler handler = new MyInvocationHandler(realMovie);
        // 动态的创建代理对象
        Movie proxy = (Movie) Proxy.newProxyInstance(
                RealMovie.class.getClassLoader(), // 类加载器
                new Class[]{Movie.class}, // 代理类要实现的接口列表
                handler // 调用处理器
        );

        // 通过代理对象调用方法
        proxy.play();
    }
}
